package com.s2015.doors.dao.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.s2015.doors.beans.MaterialType;
import com.s2015.doors.beans.Profile;
import com.s2015.doors.beans.ProfileSeries;
import com.s2015.doors.beans.User;
import com.s2015.doors.beans.Vendor;
import com.s2015.doors.beans.WindowSeries;
import com.s2015.doors.beans.WindowType;
import com.s2015.doors.dao.IWindowDao;

@Component(value="windowDao")
public class WindowDaoImpl implements IWindowDao{
	@Autowired
	private HibernateTemplate template = null;
	public HibernateTemplate getTemplate() {
		return template;
	}
	public void setTemplate(HibernateTemplate template) {
		this.template = template;
	}
	
	
	public Vendor getVendorByID(Long id){
		return template.get(Vendor.class, id);
	}
	
	public MaterialType getMaterialTypeByID(Long id){
		return template.get(MaterialType.class, id);
	}
	
	public WindowSeries getWindowSeriesByID(Long id){
		return template.get(WindowSeries.class, id);
	}
	
	public ProfileSeries getProfileSeriesByID(Long id){
		return template.get(ProfileSeries.class, id);
	}
	
	public WindowType getWindowTypeByID(Long id){
		return template.get(WindowType.class, id);
	}
	
	public Profile getProfileByID(Long id){
		return template.get(Profile.class, id);
	}

	@Override
	public List<Vendor> getVendorsByUserID(final Long id) {
		
		List executeFind = template.executeFind(new HibernateCallback<List<Vendor>>() {
			public List<Vendor> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = session.createCriteria(Vendor.class).add(Restrictions.eq("user.id", id));
				return c.list();
			}
		});
		return executeFind;
	}
	public List<Vendor> getVendorsByUser(User user) {
		return getVendorsByUserID(user.getId());
	}

	@Override
	public List<MaterialType> getMaterialTypesByVendorID(Long id) {
		Vendor vendor = template.get(Vendor.class, id);
		if(vendor == null){
			return null;
		}
		Set<MaterialType> mts = vendor.getMaterialTypes();
		List<MaterialType> resultList = null;
		if(mts != null && mts.size()>0){
			resultList = new ArrayList<MaterialType>(mts);
		}
		return resultList;
	}
	public List<MaterialType> getMaterialTypesByVendor(Vendor vendor) {
		return getMaterialTypesByVendorID(vendor.getId());
	}

	@Override
	public List<WindowSeries> getWindowSsByVendorID(Long id) {
		Vendor vendor = template.get(Vendor.class, id);
		if(vendor == null){
			return null;
		}
		Set<WindowSeries> res = vendor.getWindowSs();
		List<WindowSeries> resultList = null;
		if(res != null && res.size()>0){
			resultList = new ArrayList<WindowSeries>(res);
		}
		return resultList;
	}
	public List<WindowSeries> getWindowSsByVendor(Vendor vendor) {
		return getWindowSsByVendorID(vendor.getId());
	}
	//--------------------
	@Override
	public List<ProfileSeries> getProfileSsByVendorID(final Long id) {
		List<ProfileSeries> returnList = template.executeFind(new HibernateCallback<List<ProfileSeries>>() {
			public List<ProfileSeries> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = session.createCriteria(ProfileSeries.class).add(Restrictions.eq("vendor.id", id));
				return c.list();
			}
		});
		return returnList;
	}
	public List<ProfileSeries> getProfileSeriessByVendor(Vendor vendor) {
		return getProfileSsByVendorID(vendor.getId());
	}

	@Override
	public List<WindowType> getWindowTypesByVendorID(final Long id) {
		List<WindowType> returnList = template.executeFind(new HibernateCallback<List<WindowType>>() {
			public List<WindowType> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = session.createCriteria(WindowType.class).add(Restrictions.eq("vendor.id", id));
				return c.list();
			}
		});
		return returnList;
	}
	public List<WindowType> getWindowTypesByVendor(Vendor vendor) {
		return getWindowTypesByVendorID(vendor.getId());
	}
	
	
	@Override
	public List<Profile> getProfilesByInfo(final Long mt_id, final Long ws_id,
			final Long wt_id, final Long ps_id) {
		List<Profile> returnList = template.executeFind(new HibernateCallback<List<Profile>>() {
			public List<Profile> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = session.createCriteria(Profile.class)
						.add(Restrictions.eq("materialType.id", mt_id))
						.add(Restrictions.eq("windowSeries.id", ws_id))
						.add(Restrictions.eq("windowType.id", wt_id))
						.add(Restrictions.eq("profileSeries.id", ps_id));
				return c.list();
			}
		});
		return returnList;
	}
	public List<Profile> getProfilesByInfo(MaterialType mt,
			WindowSeries ws, WindowType wt, ProfileSeries ps) {
		return getProfilesByInfo(mt.getId(),ws.getId(),wt.getId(),ps.getId());
	}

	//================================下面是add===========================
	
	
	@Override
	public void addVendor(Vendor vendor) throws Exception {
		template.save(vendor);
	}

	@Override
	public void addWindowType(WindowType wt) throws Exception {
		template.save(wt);
	}

	@Override
	public void addProfileSs(ProfileSeries ps) throws Exception {
		template.save(ps);
	}

	@Override
	public void addProfile(Profile profile) throws Exception {
		template.save(profile);
	}
	
	//================================下面是update===========================

	@Override
	public void updateProfile(Profile newProfile) throws Exception {
		template.update(newProfile);
	}

	@Override
	public void updateVendor(Vendor newVendor) throws Exception {
		template.update(newVendor);
	}

	@Override
	public void updateWindowType(WindowType newWt) throws Exception {
		template.update(newWt);
	}

	@Override
	public void updateProfileSeries(ProfileSeries newPs) throws Exception {
		template.update(newPs);
	}

	//================================下面是delete===========================

	
	@Override
	public void deleteProfile(Profile prof) throws Exception {
		template.delete(prof);
	}
	public void deleteProfileById(Long profileID) throws Exception {
		template.delete(new Profile(profileID));
	}

	@Override
	public void deleteVendor(Vendor vend) throws Exception {
		template.delete(vend);
	}
	public void deleteVendorByID(Long vendorID) throws Exception {
		template.delete(new Vendor(vendorID));
	}

	@Override
	public void deleteWindowType(WindowType tw) throws Exception {
		template.delete(tw);
	}
	public void deleteWindowTypeByID(Long WindowTypeID) throws Exception {
		template.delete(new WindowType(WindowTypeID));
	}

	@Override
	public void deleteProfileSeries(ProfileSeries ps) throws Exception {
		template.delete(ps);
	}
	public void deleteProfileSeriesByID(Long profileSeriesID) throws Exception {
		template.delete(new ProfileSeries(profileSeriesID));
	}
	
	//=================================================================
	
	private List getInfoByPaging(final String hql,final int offset,final int length){
		List returnList = template.executeFind(new HibernateCallback<List>() {

			@Override
			public List doInHibernate(Session session)
					throws HibernateException, SQLException {
		        Query query = session.createQuery(hql);
                query.setFirstResult(offset);
                query.setMaxResults(length);
                List list = query.list();
                return list;
			}
			
		});
		return returnList;
	}
	
	private <T> List<T> getInfoByPaging(final Class<T> clazz,final int offset,final int length){
		List<T> returnList = template.executeFind(new HibernateCallback<List>() {

			@Override
			public List<T> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria cc = session.createCriteria(clazz);
				cc.setFirstResult(offset);
				cc.setMaxResults(length);
                return cc.list();
			}
			
		});
		return returnList;
	}
	
	@Override
	public List<Profile> getProfileByPaging(int offset, int length) {
		return getInfoByPaging(Profile.class,offset,length);
	}
	
}
